Redis RDB和AOF持久化和数据恢复方式以及DB常用指令
RDB 快照持久化方式
RDB(Redis Database)在指定的时间间隔内,将内存中的全量数据生成一个二进制快照文件(dump.rdb)。类似于“拍照片”。核心配置参数:
1 | # 触发机制:save <秒> <修改次数> |
优点:恢复大数据集速度极快;文件紧凑,适合异地备份。
缺点:数据丢失风险大(上次备份到宕机之间的数据会丢失);fork 子进程时在大内存环境下可能导致瞬时卡顿。
AOF 追加日志持久化方式
AOF (Append Only File):记录每一个写操作指令,以追加的方式写入文件(appendonly.aof)。类似于“记账本”。核心配置参数:
1 | appendonly yes # 开启 AOF |
优点:数据最安全(最多丢失1秒数据);日志可读,可以手动修复(如误删后删掉 AOF 末尾的 FLUSHALL 指令)。
缺点:文件体积比 RDB 大;数据恢复速度慢(需要逐条回放指令)。
生产环境最佳实践
建议采用 “混合持久化” 策略:
策略:RDB + AOF 同时开启
混合模式:在 redis.conf 中设置
aof-use-rdb-preamble yes。AOF 重写时,文件前半部分是 RDB 格式(加载快),后半部分是增量指令(数据全)。异地备份:每天定时通过
cron脚本将 dump.rdb 拷贝到另一台服务器或云存储,防止物理机房故障。针对向量搜索(Valkey-Search)的优化:降低 AOF 重写频率:向量索引数据很大,频繁重写会造成磁盘 IO 飙升。建议将
auto-aof-rewrite-min-size(默认64mb)调大(如 512mb 或 1gb)。硬件级保障:
- 使用 SSD:Redis 持久化非常依赖磁盘的随机写入性能,SSD 是必须的。
- 预留内存:Linux 在 fork 时需要一定的内存余量。建议系统内存占用不要超过 70%,并设置
vm.overcommit_memory = 1。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27# 在配置 Redis 持久化(尤其是 BGSAVE)时,vm.overcommit_memory = 1 是 Linux 内核参数中
# 最核心的一个。如果不设置它,在高负载下你的 Redis 经常会因为“内存不足”而备份失败,甚至崩溃。
# 简单来说,它是 Linux 处理内存分配的一种策略。
## 默认状态 (0):当 Redis 请求内存(比如 fork 子进程做快照)时,内核会进行启发式估算。如果它认为内存可能不够,就会拒绝该请求。
## 激进状态 (1):内核总是允许内存分配请求,直到物理内存真的用完。
## 设置成 1 后,内核会相信 Redis,直接允许 fork,从而保证持久化任务顺利开启。
# 临时生效(立即生效,重启失效)
echo 1 > /proc/sys/vm/overcommit_memory
# 或者
sysctl -w vm.overcommit_memory=1
# 永久生效(推荐)
vi /etc/sysctl.conf
# 在文件末尾添加一行
vm.overcommit_memory = 1
# 加载配置使其生效
sysctl -p
## 关闭linux内存大页
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
# 确保 net.core.somaxconn 至少设为 2048,匹配 Redis 的高并发需求。
net.core.somaxconn = 2048
误操作后怎么快速恢复!
比如执行了 FLUSHALL 后能否恢复数据,取决于你的 持久化配置(AOF 或 RDB)以及你反应的速度。请立即按照以下步骤进行“抢救”:
第一步:保持冷静,立即阻止任何新的写入:一旦发现误操作,不要重启 Redis(除非你没开 AOF),因为重启可能会触发新的持久化操作,覆盖掉现有的备份文件。
第二步:根据持久化方式选择恢复方案
场景 A:你开启了 AOF(最稳妥的恢复方式):
由于 AOF 记录的是每一条写命令,FLUSHALL 也会作为一个命令记在日志文件的末尾。你只需要把这一条删掉即可。
立即备份 AOF 文件:防止后续操作失误。
1
2
3
4
5
6
7
8
9# 如果是单纯的aof方式:
cp appendonly.aof appendonly.aof.bak
# 如果是混合rdb+aof方式:你会看到类似的至少三个文件:
# appendonly.aof.2.base.rdb:基础文件,这是混合持久化的核心,是上一次AOF重写时的内存全量快照(RDB格式)。
# appendonly.aof.2.incr.aof:增量文件,它记录了从上一次生成 .base.rdb 之后的所有写命令。你的 FLUSHALL 命令就写在这个文件的末尾。
# appendonly.aof.manifest:清单文件,告诉 Redis:当前的 AOF 由哪个 Base 文件和哪些 Incr 文件组成,以及它们的序列号(这里是 2),Redis 启动时会先读它。
mkdir /root/redis_backup
cp appendonly.aof.* /root/redis_backup/打开 AOF 文件进行编辑:
1
2
3vim appendonly.aof 或者 vim appendonly.aof.2.incr.aof
# 删除末尾的 FLUSHALL 命令:
# 滚动到文件最底部,你会看到类似 *1\r\n$8\r\nFLUSHALL 这样的记录。将其彻底删除。重启 Redis 实例: Redis 会重新读取修改后的 AOF 文件,数据就会像 “录像回放”一样全部回来(除了那条被你删掉的清空命令)。
场景 B:你只开启了 RDB:这种情况比较看运气,取决于 FLUSHALL 之后是否触发了新的 RDB 备份。
检查 dump.rdb 文件的时间戳: 如果 dump.rdb 的最后修改时间是在你执行 FLUSHALL 之前,那么你非常幸运。立即备份 dump.rdb 文件。
立即强制关闭 Redis 进程(不要执行正常的
shutdown,因为正常关机会尝试保存当前内存状态,即清空后的状态):1
2
3# 千万不要执行 redis-cli shutdown,因为正常退出可能再次触发持久化。
ps -ef | grep redis
kill -9 [Redis的PID]把备份的 dump.rdb 拷贝回数据目录。
重启 Redis,数据会恢复到上一次快照时的状态。
场景 C:你开启了混合持久化(AOF 头部是 RDB)
- 操作逻辑同 场景 A。依然是编辑 appendonly.aof,找到末尾的文本部分(AOF 混合模式下,文件末尾通常是正常的 AOF 文本指令),删掉 FLUSHALL 即可。
第三步:最后的 “核武器”——冷备份:如果你之前按照我建议的生产环境最佳实践,做了异地备份(比如每天凌晨拷贝一次
dump.rdb到另一台机器),那么你可以拿昨天的备份文件进行恢复。虽然会丢失今天的数据,但总好过全量丢失。最后:为了防止你的redis数据再次遭遇这种 “灭顶之灾”,请务必执行以下操作:
1
2
3
4
5
6
7
8
9# 重命名命令(最有效): 在 redis.conf 中加入:
rename-command FLUSHALL "OWLIAS_DANGEROUS_CLEAN_ALL"
rename-command FLUSHDB "" # 彻底禁用
rename-command CONFIG "OWLIAS_ADMIN_CONFIG"
# 权限控制: 确保生产环境的 Redis 开启了 requirepass 密码认证,避免脚本或外部工具误触。
# 开启 AOF
# 正如你看到的,AOF 是唯一能让你“反悔” 的后悔药。
异地定时备份脚本
第一步:
$ vim /root/scripts/redis_backup.sh
$ chmod +x /root/scripts/redis_backup.sh
1 |
|
第二步:配置 SSH 免密登录(核心)
在 Redis 服务器运行:
ssh-keygen -t rsa(一路回车)。拷贝公钥到备份服务器:
ssh-copy-id user@remote_ip。
第三步:设置定时任务 (Crontab)
执行 crontab -e,添加以下行,设置为每天凌晨 3:00 运行:
1 | 00 03 * * * /bin/bash /root/scripts/redis_backup.sh >> /var/log/redis_backup_cron.log 2>&1 |
DB相关的常用指令
1 | ## 数据库切换与基础管理 |
[注意]:
- Redis 集群模式下不支持多数据库,只能使用 DB 0,因此在集群环境下执行 save/bgsave/bgrewriteaof 等指令,本质上就是针对该节点唯一的 DB 0 进行持久化。
- 自动化胜过手动:在你的 redis.conf 中配置 save 规则(如 save 900 1)或开启 appendonly yes。Redis 会自动在后台调用 BGSAVE 或重写 AOF,不需要你手动执行。
- 如果你以后将应用部署到集群环境,备份时需要编写脚本,循环登录到每一个 Master 节点去执行 BGSAVE,并把每个节点的 dump.rdb 都拷贝出来。
- 除非是在停机维护或极端紧急情况下,否则永远不要在生产环境执行 SAVE。